package com.dragon.mmochat.service;

import java.awt.Color;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import com.dragon.mmochat.MmochatConstant;
import com.dragon.mmochat.MmochatMain;
import com.dragon.mmochat.message.Mmochat_21_10C;
import com.dragon.mmochat.message.Mmochat_21_1C;
import com.dragon.mmochat.message.Mmochat_21_2C;
import com.dragon.mmochat.message.Mmochat_21_3C;
import com.dragon.mmochat.message.Mmochat_21_4C;
import com.dragon.mmochat.message.Mmochat_21_5C;
import com.dragon.mmochat.message.Mmochat_21_6C;
import com.dragon.mmochat.message.Mmochat_21_7C;
import com.dragon.mmochat.message.Mmochat_21_8C;
import com.dragon.mmochat.message.Mmochat_21_9C;
import com.dragon.mmochat.model.enumType.MmochatSmallMoneyCostType;
import com.dragon.mmochat.model.enumType.MmochatSmallMoneyEarnType;
import com.dragon.mmochat.model.enumType.MmochatStoneBetResult;
import com.dragon.mmochat.model.enumType.MmochatStoneBetState;
import com.dragon.mmochat.model.enumType.MmochatStoneBetType;
import com.dragon.mmochat.model.playerBet.MmochatStoneBet;
import com.dragon.mmochat.model.role.MmochatPlayer;
import com.dragon.mmochat.util.CreateTlvWin;
import com.dragon.mmochat.util.MmochatUtil;
import com.skymobi.handler.SkymobiHandler;
import com.skymobi.message.SkymobiProtocolMessage;
import com.skymobi.message.widget.AddDataTLV;
import com.skymobi.message.widget.ClearDataTLV;
import com.skymobi.message.widget.CloseWinTLV;
import com.skymobi.message.widget.CreateMsgBoxTLV;
import com.skymobi.message.widget.SendDataTLV;
import com.skymobi.message.widget.ShowWaitingMsgBoxTLV;
import com.skymobi.message.widget.WinType;
import com.skymobi.service.SkymobiService;
import com.skymobi.util.Text;

//玩家间的赌
public class MmochatPlayerBetService {

	public static ScheduledExecutorService checkBetThread = Executors
			.newScheduledThreadPool(1);

	// betId-->bet
	public static Map<Integer, MmochatStoneBet> stoneBets = new ConcurrentHashMap<Integer, MmochatStoneBet>();

	// 写日志的buffer
	public static Map<Integer, MmochatStoneBet> recordBets = new ConcurrentHashMap<Integer, MmochatStoneBet>();

	// 比赛金额类型
	public static int[] stoneBetMoneyType = new int[] { 20000, 100000, 500000,
			2000000, 5000000 };

	public MmochatPlayerBetService() {
		checkBetThread.scheduleWithFixedDelay(new CheckBet(), 60, 60,
				TimeUnit.SECONDS);
	}

	public class CheckBet implements Runnable {
		@Override
		public void run() {
			try {
				// 删除过期的比赛
				for (MmochatStoneBet bet : stoneBets.values()) {
					try {
						// 删除超时未创建成功的单子
						if (bet.isCreateTimeOut()) {
							bet.setState(MmochatStoneBetState.创建超时);
							stoneBets.remove(bet.getId());
							continue;
						}
						// 完成后，生命时间超时
						if (bet.isLifeTimeOut()) {
							stoneBets.remove(bet.getId());
							continue;
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}

				// 定时写入文件
				try {
					if (recordBets.size() >= 30) {
						List<MmochatStoneBet> list = new ArrayList<MmochatStoneBet>(
								recordBets.values());
						recordBets.clear();
						String info = "";
						for (MmochatStoneBet bet : list) {
							// 例如:s123|k124|主办方胜|20000|小胡|小明
							info += "s" + bet.getSendRoleId() + "|k"
									+ bet.getKickRoleId() + "|";
							info += bet.getResult().toString() + "|"
									+ bet.getMoney() + "|";
							info += bet.getSendName() + "|" + bet.getKickName();
							info += "\r\n";
						}

						SimpleDateFormat time = new SimpleDateFormat(
								"yyyy-MM-dd");
						String curTime = time.format(new Date());
						String fileName = "stoneBet/bet_" + curTime;
						MmochatUtil.writeToFile(fileName, info);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	// 查看列表
	@SkymobiService
	public SkymobiProtocolMessage handleC_21_1(SkymobiHandler handler,
			Mmochat_21_1C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		switch (req.getIndex()) {
		case 1: {
			// 查看所有比赛
			CreateTlvWin tlv = new CreateTlvWin();
			tlv.setWinType(WinType.List);
			tlv.setLeftName("查看");
			tlv.setRightName("取消");
			tlv.setTitle("查看所有比赛");
			tlv.setWinHeight(208);
			tlv.addRightTLV(new CloseWinTLV());

			for (int moneyType : stoneBetMoneyType) {
				int count = 0;
				for (MmochatStoneBet bet : stoneBets.values()) {
					if (bet.getMoney() == moneyType
							&& bet.getState() == MmochatStoneBetState.等待对手) {
						count++;
					}
				}

				tlv.addItemEvent(MmochatUtil.getColorMoney(moneyType) + "文赛场\n"
						+ "数量:" + count + "场", new ClearDataTLV(),
						new AddDataTLV((int) moneyType));
			}

			tlv.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
					MmochatMain.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_21_5, (int) me
							.getRoleId()));
			ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
			tlv.addLeftTLV(wait);

			return MmochatUtil.tlvResponse(req.getHallState(), tlv);
		}
		case 2: {
			// 发布我的比赛
			CreateTlvWin tlv = new CreateTlvWin();
			tlv.setWinType(WinType.Text);
			tlv.setLeftName("发布");
			tlv.setRightName("返回");
			tlv.setTitle("发布我的比赛");
			tlv.setWinHeight(208);
			tlv.addRightTLV(new CloseWinTLV());
			String content = "";
			content += MmochatUtil.wrapColor("[规则说明]\n", Color.yellow);
			content += "点击发布按钮后，您需要选择本次比赛您出石头、剪刀还是布，然后设置比赛金钱，"
					+ "设置后，此金钱会先从您包裹中扣除。\n";
			content += "其它玩家看到后，可以拿出相应的比赛金钱与您比赛，" + "对方也选择出石头、剪刀还是布，然后根据："
					+ "石头胜剪刀、剪刀胜布、布胜石头，判定谁胜谁负。胜的一方赢的对方的钱。\n\n";
			content += MmochatUtil.wrapColor("[税费说明]\n", Color.yellow);
			content += "比赛税费由赢的一方出，直接从赢的一方赢得的钱中扣除，税费为"
					+ MmochatConstant.stoneBetTax
					+ "%。例如比赛金额为100万，则输的一方扣除100万，赢的一方赢得"
					+ (100 - MmochatConstant.stoneBetTax)
					+ "万!\n如果双方打成平手，则不扣除税费，并返还双方金钱。";
			tlv.setContent(new Text(content));

			tlv.addLeftTLV(new ClearDataTLV());
			tlv.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
					MmochatMain.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_21_2, (int) me
							.getRoleId()));
			tlv.addLeftTLV(new ShowWaitingMsgBoxTLV());

			return MmochatUtil.tlvResponse(req.getHallState(), tlv);
		}
		case 3: {
			// 查看我的比赛
			CreateTlvWin tlv = new CreateTlvWin();
			tlv.setWinType(WinType.List);
			tlv.setLeftName("确定");
			tlv.setRightName("取消");
			tlv.setTitle("查看我的比赛");
			tlv.setWinHeight(208);
			tlv.addRightTLV(new CloseWinTLV());

			List<MmochatStoneBet> notFinishBets = new ArrayList<MmochatStoneBet>();
			List<MmochatStoneBet> finishBets = new ArrayList<MmochatStoneBet>();
			for (MmochatStoneBet bet : stoneBets.values()) {
				if (bet.getSendRoleId() == me.getRoleId()) {
					if (bet.getState() == MmochatStoneBetState.等待对手) {
						notFinishBets.add(bet);
					} else if (bet.getState() == MmochatStoneBetState.比赛完成) {
						finishBets.add(bet);
					}
				}
			}
			Collections.sort(notFinishBets);
			for (MmochatStoneBet bet : notFinishBets) {
				String item = "[进行中]" + bet.getMoney() + "文";
				tlv.addItemEvent(item, new ClearDataTLV(), new AddDataTLV(
						(int) bet.getId()));
			}
			int index = 0;
			Collections.sort(finishBets);
			for (MmochatStoneBet bet : finishBets) {
				String item = "";
				if (bet.getResult() == MmochatStoneBetResult.主办方胜) {
					item += MmochatUtil.wrapColor("[赢]+" + bet.getWinMoney()
							+ "文", Color.yellow);
				} else if (bet.getResult() == MmochatStoneBetResult.挑战方胜) {
					item += MmochatUtil.wrapColor(
							"[输]-" + bet.getMoney() + "文", Color.magenta);
				} else if (bet.getResult() == MmochatStoneBetResult.平局) {
					item += MmochatUtil.wrapColor("[平局]+0文", Color.green);
				}
				item += "\n挑战者:" + bet.getKickName() + "(ID:"
						+ Integer.toHexString(bet.getKickRoleId() * 3);
				tlv.addItemEvent(item, new ClearDataTLV(), new AddDataTLV(
						(int) bet.getId()));
				index++;
				if (index >= 30) {
					break;
				}
			}

			tlv.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
					MmochatMain.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_21_9, (int) me
							.getRoleId()));
			ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
			tlv.addLeftTLV(wait);

			return MmochatUtil.tlvResponse(req.getHallState(), tlv);
		}
		default:
			break;
		}
		return null;
	}

	// 创建比赛
	@SkymobiService
	public SkymobiProtocolMessage handleC_21_2(SkymobiHandler handler,
			Mmochat_21_2C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		// 检测数量
		int count = 0;
		for (MmochatStoneBet bet : stoneBets.values()) {
			if (bet.getSendRoleId() == me.getRoleId()
					&& bet.getState() == MmochatStoneBetState.等待对手) {
				count++;
				if (count >= MmochatConstant.maxStoneBetPerRole) {
					return MmochatUtil.msgbox(req.getHallState(),
							"您当前创建的比赛数量已达上限!");
				}
			}
		}

		MmochatStoneBet bet = new MmochatStoneBet();
		bet.setSendRoleId(me.getRoleId());
		bet.setSendName(me.getName());
		stoneBets.put(bet.getId(), bet);

		CreateTlvWin tlv = new CreateTlvWin();
		tlv.setWinType(WinType.List);
		tlv.setLeftName("确定");
		tlv.setRightName("取消");
		tlv.setTitle("选择比赛金额");
		tlv.setWinHeight(208);
		tlv.setWinId(MmochatConstant.TLV_WIN_STONEBET1);
		tlv.addRightTLV(new CloseWinTLV(MmochatConstant.TLV_WIN_STONEBET1));

		for (int moneyType : stoneBetMoneyType) {
			tlv.addItemEvent(MmochatUtil.getColorMoney(moneyType) + "文钱",
					new ClearDataTLV(), new AddDataTLV((int) moneyType));
		}
		tlv.addLeftTLV(new AddDataTLV((int) bet.getId()));

		tlv.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_21_3, (int) me.getRoleId()));
		ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
		tlv.addLeftTLV(wait);

		return MmochatUtil.tlvResponse(req.getHallState(), tlv);
	}

	// 选择金额
	@SkymobiService
	public SkymobiProtocolMessage handleC_21_3(SkymobiHandler handler,
			Mmochat_21_3C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		MmochatStoneBet bet = stoneBets.get(req.getBetId());
		if (bet == null || bet.isCreateTimeOut()
				|| bet.getState() != MmochatStoneBetState.创建中) {
			return MmochatUtil.msgbox(req.getHallState(), "此比赛已经创建超时，请重新创建!");
		}
		int money = req.getMoney();
		boolean moneyOk = false;
		for (int moneyType : stoneBetMoneyType) {
			if (money == moneyType) {
				moneyOk = true;
				break;
			}
		}
		if (!moneyOk) {
			return MmochatUtil.msgbox(req.getHallState(), "暂不支持此金额的比赛!");
		}

		if (me.getSmall_money() < money) {
			return MmochatUtil.msgbox(req.getHallState(), "您包裹里没有"
					+ MmochatUtil.getColorMoney(money) + "文钱，请选择其它金额进行发布!");
		}
		bet.setMoney(money);

		// 选择出什么
		CreateTlvWin tlv = new CreateTlvWin();
		tlv.setWinType(WinType.List);
		tlv.setLeftName("确定");
		tlv.setRightName("取消");
		tlv.setTitle("选择您出的手势");
		tlv.setWinHeight(208);
		tlv.setWinId(MmochatConstant.TLV_WIN_STONEBET2);
		tlv.addRightTLV(new CloseWinTLV(MmochatConstant.TLV_WIN_STONEBET2));

		for (MmochatStoneBetType type : MmochatStoneBetType.values()) {
			tlv.addItemEvent(type.toString(), new ClearDataTLV(),
					new AddDataTLV((int) type.getValue()));
		}
		tlv.addLeftTLV(new AddDataTLV((int) bet.getId()));

		tlv.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_21_4, (int) me.getRoleId()));
		ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
		wait.setShowCancel(false);
		tlv.addLeftTLV(wait);

		return MmochatUtil.tlvResponse(req.getHallState(), new CloseWinTLV(
				MmochatConstant.TLV_WIN_STONEBET1), tlv);
	}

	// 选择手势
	@SkymobiService
	public SkymobiProtocolMessage handleC_21_4(SkymobiHandler handler,
			Mmochat_21_4C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		MmochatStoneBet bet = stoneBets.get(req.getBetId());
		if (bet == null || bet.isCreateTimeOut()
				|| bet.getState() != MmochatStoneBetState.创建中) {
			return MmochatUtil.msgbox(req.getHallState(), "此比赛已经创建超时，请重新创建!");
		}
		MmochatStoneBetType type = MmochatStoneBetType.get(req.getBetType());
		if (type == null) {
			return MmochatUtil.msgbox(req.getHallState(), "不支持此手势!");
		}
		bet.setSendType(type);

		if (MmochatGmService.isSystemExit()) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器正在重启，请稍候再试!");
		}
		if (me.getSmall_money() < bet.getMoney()) {
			return MmochatUtil.msgbox(req.getHallState(), "您包裹里的钱不足"
					+ bet.getMoney() + "文，发布失败!");
		}

		synchronized (bet) {
			if (bet.getState() != MmochatStoneBetState.创建中) {
				return MmochatUtil.msgbox(req.getHallState(), "此比赛当前状态:"
						+ bet.getState().toString());
			}
			synchronized (me) {
				if (me.getSmall_money() < bet.getMoney()) {
					return MmochatUtil.msgbox(req.getHallState(), "您包裹里的钱不足"
							+ bet.getMoney() + "文，发布失败!");
				}
				me.addAndUpdateSmall_money(-1 * bet.getMoney());
				try {
					MmochatDao.updateRoleSmallMoney(me);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			bet.setState(MmochatStoneBetState.等待对手);
		}

		String msg = MmochatUtil.wrapColor("发布成功!", Color.green) + "本次比赛编号:"
				+ bet.getId() + "，金额:" + bet.getMoney() + "文，您选择的手势是:"
				+ bet.getSendType().toString() + "!\n您可以在<查看我的比赛>中查看此比赛的情况。";
		CreateMsgBoxTLV msgbox = new CreateMsgBoxTLV();
		msgbox.setContent(new Text(msg));
		msgbox.setLeftName("确定");
		return MmochatUtil.tlvResponse(req.getHallState(), new CloseWinTLV(
				MmochatConstant.TLV_WIN_STONEBET2), msgbox);
	}

	// 查看所有比赛
	@SkymobiService
	public SkymobiProtocolMessage handleC_21_5(SkymobiHandler handler,
			Mmochat_21_5C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		List<MmochatStoneBet> bets = new ArrayList<MmochatStoneBet>();
		for (MmochatStoneBet bet : stoneBets.values()) {
			if (bet.getMoney() == req.getMoney()
					&& bet.getState() == MmochatStoneBetState.等待对手) {
				bets.add(bet);
			}
		}
		if (bets.size() == 0) {
			return MmochatUtil.msgbox(req.getHallState(), "本赛场当前没有可进行的比赛!");
		}
		Collections.shuffle(bets);
		// 选择前30个下发
		int count = Math.min(30, bets.size());
		int index = 0;

		CreateTlvWin tlv = new CreateTlvWin();
		tlv.setWinType(WinType.List);
		tlv.setLeftName("查看");
		tlv.setRightName("返回");
		tlv.setTitle(req.getMoney() + "文赛场");
		tlv.setWinHeight(208);
		tlv.addRightTLV(new CloseWinTLV());

		for (MmochatStoneBet bet : bets) {
			index++;
			String item = MmochatUtil.wrapColor(bet.getSendName(), Color.green)
					+ "\nID:" + Integer.toHexString(bet.getSendRoleId() * 3);
			tlv.addItemEvent(item, new ClearDataTLV(), new AddDataTLV((int) bet
					.getId()));
			if (index >= count) {
				break;
			}
		}

		tlv.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_21_6, (int) me.getRoleId()));
		ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
		tlv.addLeftTLV(wait);

		return MmochatUtil.tlvResponse(req.getHallState(), tlv);
	}

	// 查看某个比赛
	private CreateTlvWin getStoneBetPage(MmochatStoneBet bet, MmochatPlayer me) {
		CreateTlvWin tlv = new CreateTlvWin();
		tlv.setWinType(WinType.Text);
		tlv.setRightName("返回");
		tlv.setTitle(bet.getSendName() + "的比赛");
		tlv.setWinHeight(208);
		tlv.setWinId(MmochatConstant.TLV_WIN_STONEBET3);
		tlv.addRightTLV(new CloseWinTLV(MmochatConstant.TLV_WIN_STONEBET3));

		String content = "";
		content += MmochatUtil.wrapColor("[发起方]\n", Color.yellow);
		content += bet.getSendName() + "\nID:"
				+ Integer.toHexString(bet.getSendRoleId() * 3) + "\n";
		content += MmochatUtil.wrapColor("[金额]\n", Color.yellow);
		content += MmochatUtil.getColorMoney(bet.getMoney()) + "文\n\n";
		switch (bet.getState()) {
		case 等待对手: {
			content += MmochatUtil.wrapColor("[挑战说明]\n", Color.yellow);
			content += "玩家"
					+ MmochatUtil.wrapColor(bet.getSendName(), Color.green)
					+ "已经选择了石头、剪刀、布中的一项，您点击挑战按钮后，"
					+ "需要从石头、剪刀、布中也选出一项，与对方比较。\n"
					+ MmochatUtil.wrapColor("胜负判定如下：石头VS剪刀，石头胜。"
							+ "剪刀VS布，剪刀胜。布VS石头，布胜。两者相同则平局。\n\n", Color.green);

			content += MmochatUtil.wrapColor("[奖励说明]\n", Color.yellow);
			content += "本场比赛金额为" + MmochatUtil.getColorMoney(bet.getMoney())
					+ "文，失败方扣除" + MmochatUtil.getColorMoney(bet.getMoney())
					+ "文钱。胜利方赢取" + MmochatUtil.getColorMoney(bet.getWinMoney())
					+ "文钱(其中扣除了" + MmochatConstant.stoneBetTax
					+ "%的税费)，平局则返还双方金钱。";

			tlv.setLeftName("挑战");

			CreateMsgBoxTLV msgbox = new CreateMsgBoxTLV();
			msgbox.setContent(new Text("您确定要以"
					+ MmochatUtil.getColorMoney(bet.getMoney())
					+ "文钱参加本次的石头剪刀布比赛么?"));
			msgbox.setLeftName("确定");
			msgbox.setRightName("取消");
			msgbox.addLeftTLV(new ClearDataTLV());
			msgbox.addLeftTLV(new AddDataTLV((int) bet.getId()));
			msgbox.addLeftTLV(new SendDataTLV(MmochatConstant
					.getClientModuleId(), MmochatMain.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_21_7, (int) me
							.getRoleId()));
			ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
			wait.setShowCancel(false);
			msgbox.addLeftTLV(wait);

			tlv.addLeftTLV(msgbox);
			break;
		}
		case 开始比赛: {
			content += MmochatUtil.wrapColor("当前已经有玩家在挑战了，请选择其它赛场!", Color.red);
			break;
		}
		case 比赛完成: {
			content += MmochatUtil.wrapColor("[挑战结果]\n", Color.yellow);
			content += bet.getSendName() + ":" + bet.getSendType().toString()
					+ "\n";
			content += bet.getKickName() + ":" + bet.getKickType().toString()
					+ "\n";
			switch (bet.getResult()) {
			case 无:
				content += MmochatUtil.wrapColor("结果:未出结果", Color.red);
				break;
			case 主办方胜:
				content += MmochatUtil.wrapColor("结果:" + bet.getSendName()
						+ "胜出!", Color.red);
				break;
			case 挑战方胜:
				content += MmochatUtil.wrapColor("结果:" + bet.getKickName()
						+ "胜出!", Color.red);
				break;
			case 平局:
				content += MmochatUtil.wrapColor("结果:平局!", Color.red);
				break;
			default:
				break;
			}
			content += "\n\n";
			content += MmochatUtil.wrapColor("[金钱结算]\n", Color.yellow);
			switch (bet.getResult()) {
			case 主办方胜:
				content += bet.getSendName()
						+ ":"
						+ MmochatUtil.wrapColor("+" + bet.getWinMoney(),
								Color.green) + "\n";
				content += bet.getKickName()
						+ ":"
						+ MmochatUtil.wrapColor("-" + bet.getMoney(),
								Color.magenta) + "\n";
				break;
			case 挑战方胜:
				content += bet.getSendName()
						+ ":"
						+ MmochatUtil.wrapColor("-" + bet.getMoney(),
								Color.magenta) + "\n";
				content += bet.getKickName()
						+ ":"
						+ MmochatUtil.wrapColor("+" + bet.getWinMoney(),
								Color.green) + "\n";
				break;
			case 平局:
				content += bet.getSendName() + ":"
						+ MmochatUtil.wrapColor("+0", Color.green) + "\n";
				content += bet.getKickName() + ":"
						+ MmochatUtil.wrapColor("+0", Color.green) + "\n";
				break;
			default:
				break;
			}
			break;
		}
		case 比赛取消: {
			content += MmochatUtil.wrapColor("发起方已经取消本次比赛!", Color.red);
			break;
		}
		default:
			break;
		}

		tlv.setContent(new Text(content));
		return tlv;
	}

	// 查看某个比赛页面
	@SkymobiService
	public SkymobiProtocolMessage handleC_21_6(SkymobiHandler handler,
			Mmochat_21_6C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		MmochatStoneBet bet = stoneBets.get(req.getBetId());
		if (bet == null || bet.getState() != MmochatStoneBetState.等待对手) {
			return MmochatUtil.msgbox(req.getHallState(),
					"该场比赛已经有人在挑战或已经结束，请选择其它比赛!");
		}

		CreateTlvWin tlv = getStoneBetPage(bet, me);
		return MmochatUtil.tlvResponse(req.getHallState(), tlv);
	}

	// 参加比赛
	@SkymobiService
	public SkymobiProtocolMessage handleC_21_7(SkymobiHandler handler,
			Mmochat_21_7C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		MmochatStoneBet bet = stoneBets.get(req.getBetId());
		if (bet == null || bet.getState() != MmochatStoneBetState.等待对手) {
			return MmochatUtil.msgbox(req.getHallState(),
					"该场比赛已经有人在挑战，请选择其它比赛!");
		}

		if (me.getRoleId() == bet.getSendRoleId()) {
			return MmochatUtil.msgbox(req.getHallState(), "您不能挑战自己!");
		}

		if (me.getSmall_money() < bet.getMoney()) {
			return MmochatUtil.msgbox(req.getHallState(), "本次比赛需要"
					+ bet.getMoney() + "文钱，您包裹中没有足够的金钱!");
		}

		// 选择出什么
		CreateTlvWin tlv = new CreateTlvWin();
		tlv.setWinType(WinType.List);
		tlv.setLeftName("确定");
		tlv.setRightName("取消");
		tlv.setTitle("选择您出的手势");
		tlv.setWinHeight(208);
		tlv.setWinId(MmochatConstant.TLV_WIN_STONEBET4);
		tlv.addRightTLV(new CloseWinTLV(MmochatConstant.TLV_WIN_STONEBET4));

		for (MmochatStoneBetType type : MmochatStoneBetType.values()) {
			tlv.addItemEvent(type.toString(), new ClearDataTLV(),
					new AddDataTLV((int) type.getValue()));
		}
		tlv.addLeftTLV(new AddDataTLV((int) bet.getId()));

		tlv.addLeftTLV(new SendDataTLV(MmochatConstant.getClientModuleId(),
				MmochatMain.getModuleInstID(),
				MmochatConstant.MSGCODE_MMOCHAT_C_21_8, (int) me.getRoleId()));
		ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
		wait.setShowCancel(false);
		tlv.addLeftTLV(wait);

		return MmochatUtil.tlvResponse(req.getHallState(), tlv);
	}

	// 参加比赛，挑战者出手势
	@SkymobiService
	public SkymobiProtocolMessage handleC_21_8(SkymobiHandler handler,
			Mmochat_21_8C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		MmochatStoneBet bet = stoneBets.get(req.getBetId());
		if (bet == null || bet.getState() != MmochatStoneBetState.等待对手) {
			return MmochatUtil.msgbox(req.getHallState(),
					"该场比赛已经有人在挑战，请选择其它比赛!");
		}

		if (me.getSmall_money() < bet.getMoney()) {
			return MmochatUtil.msgbox(req.getHallState(), "本次比赛需要"
					+ bet.getMoney() + "文钱，您包裹中没有足够的金钱!");
		}
		MmochatStoneBetType kickType = MmochatStoneBetType.get(req.getType());
		if (kickType == null) {
			return MmochatUtil.msgbox(req.getHallState(), "暂不支持此手势!");
		}

		synchronized (bet) {
			if (bet.getState() != MmochatStoneBetState.等待对手) {
				return MmochatUtil.msgbox(req.getHallState(),
						"该场比赛已经有人在挑战，请选择其它比赛!");
			}
			bet.setState(MmochatStoneBetState.开始比赛);
		}

		bet.setKickRoleId(me.getRoleId());
		bet.setKickName(me.getName());
		bet.setKickType(kickType);

		MmochatStoneBetType sendType = bet.getSendType();
		switch (sendType) {
		case 石头: {
			if (kickType == MmochatStoneBetType.石头) {
				bet.setResult(MmochatStoneBetResult.平局);
			} else if (kickType == MmochatStoneBetType.剪刀) {
				bet.setResult(MmochatStoneBetResult.主办方胜);
			} else if (kickType == MmochatStoneBetType.布) {
				bet.setResult(MmochatStoneBetResult.挑战方胜);
			}
			break;
		}
		case 剪刀: {
			if (kickType == MmochatStoneBetType.石头) {
				bet.setResult(MmochatStoneBetResult.挑战方胜);
			} else if (kickType == MmochatStoneBetType.剪刀) {
				bet.setResult(MmochatStoneBetResult.平局);
			} else if (kickType == MmochatStoneBetType.布) {
				bet.setResult(MmochatStoneBetResult.主办方胜);
			}
			break;
		}
		case 布: {
			if (kickType == MmochatStoneBetType.石头) {
				bet.setResult(MmochatStoneBetResult.主办方胜);
			} else if (kickType == MmochatStoneBetType.剪刀) {
				bet.setResult(MmochatStoneBetResult.挑战方胜);
			} else if (kickType == MmochatStoneBetType.布) {
				bet.setResult(MmochatStoneBetResult.平局);
			}
			break;
		}
		default:
			break;
		}

		// 主办主已经扣了钱，挑战者的钱还在包裹
		int sendMoney = 0, kickMoney = 0;
		String hint = "";
		String sendHint = "";
		int systemWin = 0;
		switch (bet.getResult()) {
		case 主办方胜: {
			sendMoney = bet.getMoney() + bet.getWinMoney();
			kickMoney = -1 * bet.getMoney();
			hint = MmochatUtil.wrapColor("很遗憾，您输了，扣除您" + bet.getMoney()
					+ "文钱!详情请查看赛场信息!", Color.red);
			sendHint = "您发布的编号为"
					+ bet.getId()
					+ "的石头剪刀布比赛("
					+ bet.getMoney()
					+ "文)已经结束，对手是"
					+ bet.getKickName()
					+ "。比赛结果:"
					+ MmochatUtil.wrapColor("您赢了，赢得" + bet.getWinMoney()
							+ "文，已经放到您包裹!", Color.green);
			systemWin = bet.getMoney() - bet.getWinMoney();
			break;
		}
		case 挑战方胜: {
			kickMoney = bet.getWinMoney();
			hint = MmochatUtil.wrapColor("恭喜，您赢了，您赢得" + bet.getWinMoney()
					+ "文钱!详情请查看赛场信息!", Color.green);
			sendHint = "您发布的编号为" + bet.getId() + "的石头剪刀布比赛(" + bet.getMoney()
					+ "文)已经结束，对手是" + bet.getKickName() + "。比赛结果:"
					+ MmochatUtil.wrapColor("您输了，请再接再励!", Color.red);
			systemWin = bet.getMoney() - bet.getWinMoney();
			break;
		}
		case 平局: {
			sendMoney = bet.getMoney();
			hint = MmochatUtil.wrapColor("棋逢对手，打成平手，不输不赢!详情请查看赛场信息!",
					Color.green);
			sendHint = "您发布的编号为"
					+ bet.getId()
					+ "的石头剪刀布比赛("
					+ bet.getMoney()
					+ "文)已经结束，对手是"
					+ bet.getKickName()
					+ "。比赛结果:"
					+ MmochatUtil.wrapColor("平局!比赛金" + bet.getMoney()
							+ "文钱已经返还到您包裹!", Color.green);
			systemWin = 0;
			break;
		}
		default:
			break;
		}

		if (sendMoney != 0) {
			MmochatPlayer sender = MmochatGmService.getRoleInfoById(bet
					.getSendRoleId());
			if (sender != null) {
				sender.addAndUpdateSmall_money(sendMoney);
				try {
					MmochatDao.updateRoleSmallMoney(sender);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		if (kickMoney != 0) {
			me.addAndUpdateSmall_money(kickMoney);
			try {
				MmochatDao.updateRoleSmallMoney(me);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		if (systemWin > 0) {
			// 统计系统赢的钱
			MmochatStatisticsService.addSmallMoneyCost(
					MmochatSmallMoneyCostType.石头剪刀布, -1 * systemWin);
		}

		bet.setCloseTime(System.currentTimeMillis());
		bet.setState(MmochatStoneBetState.比赛完成);

		CreateMsgBoxTLV msgbox = new CreateMsgBoxTLV();
		msgbox.setContent(new Text(hint));
		msgbox.setLeftName("确定");

		// 下发客服消息通知
		MmochatGmService.sendKufuPrivateMsg(bet.getSendRoleId(), sendHint,
				false);
		MmochatGmService.sendKufuPrivateMsg(bet.getKickRoleId(), hint, false);

		recordBets.put(bet.getId(), bet);

		CreateTlvWin tlv = getStoneBetPage(bet, me);
		return MmochatUtil.tlvResponse(req.getHallState(), new CloseWinTLV(
				MmochatConstant.TLV_WIN_STONEBET4), new CloseWinTLV(
				MmochatConstant.TLV_WIN_STONEBET3), tlv, msgbox);
	}

	// 查看我的比赛信息
	private CreateTlvWin getMyStoneBetPage(MmochatStoneBet bet, MmochatPlayer me) {
		CreateTlvWin tlv = new CreateTlvWin();
		tlv.setWinType(WinType.Text);
		tlv.setRightName("返回");
		tlv.setTitle("我的比赛");
		tlv.setWinHeight(208);
		tlv.setWinId(MmochatConstant.TLV_WIN_STONEBET5);
		tlv.addRightTLV(new CloseWinTLV(MmochatConstant.TLV_WIN_STONEBET5));

		String content = "";
		content += MmochatUtil.wrapColor("[比赛编号]\n", Color.yellow);
		content += bet.getId() + "\n\n";
		content += MmochatUtil.wrapColor("[比赛金额]\n", Color.yellow);
		content += MmochatUtil.getColorMoney(bet.getMoney()) + "文\n\n";
		content += MmochatUtil.wrapColor("[比赛进度]\n", Color.yellow);
		content += bet.getState().toString() + "\n\n";
		switch (bet.getState()) {
		case 等待对手: {
			content += MmochatUtil.wrapColor("[撤消说明]\n", Color.yellow);
			content += "点击撤消按钮，则本次比赛撤消，比赛资金会全额返还到您的包裹!"
					+ "只有比赛未开始时才能撤消。撤消后，本比赛页面将删除。\n\n";

			tlv.setLeftName("撤消");

			CreateMsgBoxTLV msgbox = new CreateMsgBoxTLV();
			msgbox.setContent(new Text("您确定撤消本次比赛么?"));
			msgbox.setLeftName("确定");
			msgbox.setRightName("取消");
			msgbox.addLeftTLV(new ClearDataTLV());
			msgbox.addLeftTLV(new AddDataTLV((int) bet.getId()));
			msgbox.addLeftTLV(new SendDataTLV(MmochatConstant
					.getClientModuleId(), MmochatMain.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_21_10, (int) me
							.getRoleId()));
			ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
			wait.setShowCancel(false);
			msgbox.addLeftTLV(wait);

			tlv.addLeftTLV(msgbox);
			break;
		}
		case 比赛完成: {
			content += MmochatUtil.wrapColor("[挑战结果]\n", Color.yellow);
			content += bet.getSendName() + ":" + bet.getSendType().toString()
					+ "\n";
			content += bet.getKickName() + ":" + bet.getKickType().toString()
					+ "\n";
			switch (bet.getResult()) {
			case 无:
				content += MmochatUtil.wrapColor("结果:未出结果", Color.red);
				break;
			case 主办方胜:
				content += MmochatUtil.wrapColor("结果:" + bet.getSendName()
						+ "胜出!", Color.red);
				break;
			case 挑战方胜:
				content += MmochatUtil.wrapColor("结果:" + bet.getKickName()
						+ "胜出!", Color.red);
				break;
			case 平局:
				content += MmochatUtil.wrapColor("结果:平局!", Color.red);
				break;
			default:
				break;
			}
			content += "\n\n";
			content += MmochatUtil.wrapColor("[金钱结算]\n", Color.yellow);
			switch (bet.getResult()) {
			case 主办方胜:
				content += bet.getSendName()
						+ ":"
						+ MmochatUtil.wrapColor("+" + bet.getWinMoney(),
								Color.green) + "\n";
				content += bet.getKickName()
						+ ":"
						+ MmochatUtil.wrapColor("-" + bet.getMoney(),
								Color.magenta) + "\n";
				break;
			case 挑战方胜:
				content += bet.getSendName()
						+ ":"
						+ MmochatUtil.wrapColor("-" + bet.getMoney(),
								Color.magenta) + "\n";
				content += bet.getKickName()
						+ ":"
						+ MmochatUtil.wrapColor("+" + bet.getWinMoney(),
								Color.green) + "\n";
				break;
			case 平局:
				content += bet.getSendName() + ":"
						+ MmochatUtil.wrapColor("+0", Color.green) + "\n";
				content += bet.getKickName() + ":"
						+ MmochatUtil.wrapColor("+0", Color.green) + "\n";
				break;
			default:
				break;
			}
			content += "\n";
			content += MmochatUtil.wrapColor("本比赛信息只保留"
					+ MmochatConstant.stoneBetDoneKeepTime + "小时!超过"
					+ MmochatConstant.stoneBetDoneKeepTime + "小时将自动删除!",
					Color.red);
			break;
		}
		default:
			break;
		}

		tlv.setContent(new Text(content));
		return tlv;
	}

	// 查看我的比赛
	@SkymobiService
	public SkymobiProtocolMessage handleC_21_9(SkymobiHandler handler,
			Mmochat_21_9C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		MmochatStoneBet bet = stoneBets.get(req.getBetId());
		if (bet == null) {
			return MmochatUtil.msgbox(req.getHallState(),
					"此比赛已经不存在，可能是已经撤消，或结束时间超过"
							+ MmochatConstant.stoneBetDoneKeepTime + "小时!");
		}

		CreateTlvWin tlv = getMyStoneBetPage(bet, me);
		return MmochatUtil.tlvResponse(req.getHallState(), tlv);
	}

	// 撤消比赛
	@SkymobiService
	public SkymobiProtocolMessage handleC_21_10(SkymobiHandler handler,
			Mmochat_21_10C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		MmochatStoneBet bet = stoneBets.get(req.getBetId());
		if (bet == null) {
			return MmochatUtil.msgbox(req.getHallState(),
					"此比赛已经不存在，可能是已经撤消，或结束时间超过"
							+ MmochatConstant.stoneBetDoneKeepTime + "小时!");
		}

		if (bet.getState() != MmochatStoneBetState.等待对手) {
			return MmochatUtil.msgbox(req.getHallState(), "当前比赛进度为:"
					+ bet.getState().toString() + ",无法撤消!");
		}

		synchronized (bet) {
			if (bet.getState() != MmochatStoneBetState.等待对手) {
				return MmochatUtil.msgbox(req.getHallState(), "当前比赛进度为:"
						+ bet.getState().toString() + ",无法撤消!");
			}
			bet.setState(MmochatStoneBetState.比赛取消);
		}

		CreateMsgBoxTLV msgbox = new CreateMsgBoxTLV();
		msgbox.setContent(new Text("比赛已经撤消!比赛资金" + bet.getMoney()
				+ "已经全额返还到您的包裹!"));
		msgbox.setLeftName("确定");

		me.addAndUpdateSmall_money(bet.getMoney());

		try {
			MmochatDao.updateRoleSmallMoney(me);
		} catch (Exception e) {
			e.printStackTrace();
		}

		stoneBets.remove(bet.getId());

		CreateTlvWin tlv = getMyStoneBetPage(bet, me);
		return MmochatUtil.tlvResponse(req.getHallState(), new CloseWinTLV(
				MmochatConstant.TLV_WIN_STONEBET5), tlv, msgbox);
	}

}
